package cc.minos.servers.openfire.managers
{
	import cc.minos.console.Console;
	import cc.minos.servers.openfire.events.LogEvent;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import org.igniterealtime.xiff.core.EscapedJID;
	import org.igniterealtime.xiff.core.XMPPBOSHConnection;
	import org.igniterealtime.xiff.core.XMPPConnection;
	import org.igniterealtime.xiff.data.im.RosterItemVO;
	import org.igniterealtime.xiff.data.Presence;
	import org.igniterealtime.xiff.events.DisconnectionEvent;
	import org.igniterealtime.xiff.events.LoginEvent;
	import org.igniterealtime.xiff.events.OutgoingDataEvent;
	import org.igniterealtime.xiff.events.XIFFErrorEvent;
	
	/**
	 * ...
	 * @author Minos
	 */
	public class ConnectionManager extends BasicManager
	{
		private var keepAliveTimer:Timer;
		private var _lastSent:int = 0;
		
		private var resource:String = "Minos#EE";
		
		public function ConnectionManager( type:String = "def" , port:int = 5222 )
		{
			switch ( type )
			{
				case "http": 
					con = new XMPPBOSHConnection( false );
					break;
				case "https": 
					con = new XMPPBOSHConnection( true );
					break;
				default: 
					con = new XMPPConnection();
			}
			con.port = port;
			super( con );
		}
		
		public function login( username:String , password:String , domain:String , server:String = null ):void
		{
			
			con.username = username;
			con.password = password;
			con.domain = domain;
			//con.server = domain;
			con.resource = resource;
			//con.
			if ( server && server!="" )
				con.server = server;
			
			con.addEventListener( OutgoingDataEvent.OUTGOING_DATA , packetSent );
			con.addEventListener( LoginEvent.LOGIN , onLogin );
			con.addEventListener( DisconnectionEvent.DISCONNECT , onDisconnect );
			con.addEventListener( XIFFErrorEvent.XIFF_ERROR , onError );
			
			con.connect( XMPPConnection.STREAM_TYPE_STANDARD );
			
			keepAliveTimer = new Timer( 15 * 1000 );
			keepAliveTimer.addEventListener( TimerEvent.TIMER , checkKeepAlive );
			keepAliveTimer.start();
		}
		
		private function onError(e:XIFFErrorEvent):void 
		{
			Console.log( e.errorMessage , this , 3 );
		}
		
		private function onDisconnect(e:DisconnectionEvent):void 
		{
			con.removeEventListener( DisconnectionEvent.DISCONNECT , onDisconnect );
			broadcastEvent( e );
		}
		
		public function logout():void
		{
			keepAliveTimer.stop();
			keepAliveTimer.removeEventListener( TimerEvent.TIMER , checkKeepAlive );
			keepAliveTimer = null;
			//
			var jid:EscapedJID = new EscapedJID( con.domain );
			var p:Presence = new Presence( jid , null , Presence.TYPE_UNAVAILABLE , null , "offline" );
			con.send( p );
			con.removeEventListener( OutgoingDataEvent.OUTGOING_DATA , packetSent );
			con.disconnect();
		}
		
		private function onLogin( e:LoginEvent ):void
		{
			con.removeEventListener( LoginEvent.LOGIN , onLogin );
			OpenFireManager.me = RosterItemVO.get( con.jid , true );
			//
			var evt:LogEvent = new LogEvent( LogEvent.LOGIN )
			evt.item = OpenFireManager.me;
			broadcastEvent( evt );
		}
		
		private function checkKeepAlive( e:TimerEvent ):void
		{
			if ( new Date().getTime() - _lastSent > 15000 )
				con.sendKeepAlive();
		}
		
		private function packetSent( e:Event ):void
		{
			_lastSent = new Date().getTime();
		}
		
		public function get connection():XMPPConnection
		{
			return con;
		}
	
	}

}